﻿using Filters;
using Furion.DataEncryption;
using Furion.DataEncryption.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq.Expressions;

namespace Services;

/// <summary>
/// 商户服务
/// </summary>
[Authorize, Store, ApiDescriptionSettings("商户")]
public class StoreServices : BaseServices
{
    private readonly ISqlSugarClient db;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="db"></param>
    public StoreServices(ISqlSugarClient db)
    {
        this.db = db;
    }

    /// <summary>
    /// 登录
    /// </summary>
    /// <param name="phone"></param>
    /// <param name="pwd"></param>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<object> Login(string phone, string pwd)
    {
        var data = await db.Queryable<Entity.Store>().FirstAsync(x => x.Phone == phone);

        if (data is null) return No("账号密码错误");

        if (data.Pwd != pwd.ToSHA1Encrypt(true)) return No("账号密码错误");

        var token = JWTEncryption.Encrypt(new Dictionary<string, object>
        {
            { "StoreId", data.Id },

            { "Role", Enums.TokenRole.商家 }
        });

        return Ok(new { token });
    }

    /// <summary>
    /// 详情
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetDetail()
    {
        var store = await db.Queryable<Entity.Store>().FirstAsync(x => x.Id == STOREID);

        return Ok(store);
    }

    /// <summary>
    /// 获取支付成功的订单信息
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public async Task<object> GetOrder(int type)
    {
        var order = await db.Queryable<Entity.Order>()

            .Where(x => x.StoreId == STOREID)

            .Where(x => x.PayStatus == Entity.PayStatus.已支付)

            .WhereIF(type >= 0, x => x.OrderType == (Entity.OrderType)type)

            .OrderBy(x => x.Id, OrderByType.Desc)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(order);
    }

    /// <summary>
    /// 获取订单
    /// </summary>
    /// <param name="payState">支付状态</param>
    /// <param name="orderType">订单类型</param>
    /// <returns></returns>
    public async Task<object> GetOrder(int payState, int orderType)
    {
        var order = await db.Queryable<Entity.Order>()

            .Where(x => x.StoreId == STOREID)

            .WhereIF(payState >= 0, x => x.PayStatus == (Entity.PayStatus)payState)

            .WhereIF(orderType >= 0, x => x.OrderType == (Entity.OrderType)orderType)

            .Includes(x => x.Client)

            .OrderBy(x => x.Id, OrderByType.Desc)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(order);
    }

    /// <summary>
    /// 门店下的用户信息
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetUserInfo([FromQuery] string name)
    {

        string sql = $@"SELECT c.id,c.name,c.phone,c.avatar,o.* FROM `client` as c

                        left join 

                        (select count(0) orderCount ,sum(payprice) totalPrice ,max(created) lastTime , userid from `order` where storeid = {STOREID} and paytype = 1 

                        group by userid) as o

                        on c.id = o.userid
                        
                        where  o.orderCount > 0 and c.name like '%{name}%'

                        order by c.BindUserInfo = 1 desc ";

        var data = await db.SqlQueryable<dynamic>(sql).ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 图表数据
    /// </summary>
    /// <param name="fmt"></param>
    /// <returns></returns>
    public async Task<object> GetChart(string fmt)
    {
        string fmtInfo = "%Y-%m-%d";

        string showInfo = "%Y-%m-%d";

        if (fmt == "month")
        {
            fmtInfo = "%Y-%m";

            showInfo = "%m";
        }

        if (fmt == "day")
        {
            fmtInfo = "%Y-%m-%d";

            showInfo = "%d";
        }

        if (fmt == "year")
        {
            fmtInfo = "%Y";

            showInfo = "%Y";
        }

        string sql = $@"select 
                        sum(storePrice) as price , DATE_FORMAT(created,'{showInfo}') as time , count(0) as count
                        from `order` 
                        where PayStatus = 1 and StoreId = {STOREID}
                        GROUP BY DATE_FORMAT(created,'{fmtInfo}')";

        var data = await db.SqlQueryable<dynamic>(sql).ToListAsync();

        return Ok(data);
    }

    /// <summary>
    /// 系统客服
    /// </summary>
    /// <returns></returns>
    public async Task<object> SystemServices()
    {
        return Ok(await Task.FromResult(new
        {
            description = "您在系统使用中有任何问题,可以直接联系系统客服",

            phone = new object[]
            {
                new { name  = "商务客服" , phone = "15235532839" },
                new { name  = "技术客服" , phone = "15934340475" },
                new { name  = "商家客服" , phone = "13246720172" }
            }
        }));
    }

    /// <summary>
    /// 重置密码
    /// </summary>
    /// <param name="newPwd">新密码</param>
    /// <returns></returns>
    public async Task<object> Retpwd(string newPwd)
    {
        var store = await db.Queryable<Entity.Store>().FirstAsync(x => x.Id == STOREID);

        string code = await RedisHelper.GetAsync($"PHONECODE_{store.Phone}");

        store.Pwd = newPwd.ToSHA1Encrypt(true);

        bool state = await db.Updateable(store).UpdateColumns("pwd").ExecuteCommandHasChangeAsync();

        return Msg(state, error: "修改失败,请重试");
    }

    /// <summary>
    /// 商户流水统计
    /// </summary>
    /// <param name="payType">支付类型 全部传入-1</param>
    /// <returns></returns>
    public async Task<object> GetStoreOrderSum(int payType)
    {
        var now = DateTime.Now;

        var day7 = await db.Queryable<Entity.Order>().Where(x => x.StoreId == STOREID)

             .WhereIF(payType > -1, x => x.PayType == (Entity.PayType)payType)

              .Where(x => x.PayStatus == Entity.PayStatus.已支付)

            .Where("YEARWEEK(created) = YEARWEEK(CURDATE())")

            .Select<dynamic>("count(0) num ,sum(payPrice) price").FirstAsync();

        var day30 = await db.Queryable<Entity.Order>().Where(x => x.StoreId == STOREID)

           .WhereIF(payType > -1, x => x.PayType == (Entity.PayType)payType)

            .Where(x => x.PayStatus == Entity.PayStatus.已支付)

           .Where(x => x.Created.ToString("yyyyMM") == DateTime.Now.ToString("yyyyMM"))

           .Select<dynamic>("count(0) num ,sum(payPrice) price").FirstAsync();

        var day90 = await db.Queryable<Entity.Order>().Where(x => x.StoreId == STOREID)

           .WhereIF(payType > -1, x => x.PayType == (Entity.PayType)payType)

            .Where(x => x.PayStatus == Entity.PayStatus.已支付)

            .Where(x => x.Created.ToString("yyyy") == DateTime.Now.ToString("yyyy"))

           .Select<dynamic>("count(0) num ,sum(payPrice) price").FirstAsync();



        return Ok(new { day7, day30, day90 });
    }

    /// <summary>
    /// 收支明细
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public async Task<object> GetMoneylog(int type)
    {
        var data = await db.Queryable<Entity.StoreMoneyLog>()

            .Where(x => x.UID == STOREID && x.ChangeType == type)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 资金汇总
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetMoneySum()
    {
        var teambuy = await db.Queryable<Entity.StoreMoneyLog>().Where(x => x.UID == STOREID).Where(x => x.MoneyType == Entity.MoneyType.拼团返佣 && x.Created.ToString("yyyyMMdd") == DateTime.Now.ToString("yyyyMMdd")).SumAsync(x => x.Money);

        var teambuyHistory = await db.Queryable<Entity.StoreMoneyLog>().Where(x => x.UID == STOREID).Where(x => x.MoneyType == Entity.MoneyType.拼团返佣).SumAsync(x => x.Money);

        var active = await db.Queryable<Entity.StoreMoneyLog>().Where(x => x.UID == STOREID).Where(x => x.MoneyType == Entity.MoneyType.排队收益 && x.Created.ToString("yyyyMMdd") == DateTime.Now.ToString("yyyyMMdd")).SumAsync(x => x.Money);

        var activeHistory = await db.Queryable<Entity.StoreMoneyLog>().Where(x => x.UID == STOREID).Where(x => x.MoneyType == Entity.MoneyType.排队收益).SumAsync(x => x.Money);

        return Ok(new { teambuy, teambuyHistory, active, activeHistory });
    }
}
